package com.sxj.corejava.code01_线程;

/**
 * @author 石小俊
 * @version 1.0
 * @date 2023年11月14日 19:30
 */
public class Test04_线程安全问题 {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        // 参数二:表示自定义线程名
        Thread t1 = new Thread(ticket,"窗口1");
        Thread t2 = new Thread(ticket,"窗口2");
        Thread t3 = new Thread(ticket,"窗口3");
        t1.start();
        t2.start();
        t3.start();
        // 每一个线程都设置了休眠时间10毫秒,此时运行之后发现出现了有问题的票,例如:0和-1
        // 此时假设票卖到了最后一张,三个线程都进来了
        // 第一个线程进来后发现票号为1,满足条件
        // 此时第一个线程休眠
        // 此时第二个线程进来,发现票号还是1满足条件,此时第二个线程也休眠了
        // 第三个线程进来,发现票号还是1满足条件,此时第三个线程也休眠了
        // 第一个线程休眠时间到,继续执行,输出票号为1,执行票号-1的操作,导致票号变为0
        // 第二个线程休眠时间到,继续执行,输出票号为0,执行票号-1的操作,导致票号变为-1
        // 第三个线程休眠时间到,继续执行,输出票号为-1,执行票号-1的操作,导致票号变为-2
           }
}
class Ticket implements Runnable{

    private static int num = 100;// 共100张票

//    @Override
//    public void run() {
//        while (true) {
//            synchronized (this) {
//                if (num > 0) {
//                    try {
//                        Thread.sleep(10);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                    System.out.println(Thread.currentThread().getName() + "正在出票,票号为:" + num--);
//                }
//            }
//        }
//    }

    @Override
    public void run() {
        while (true){
            sellTicket();
        }
    }

    public static synchronized  void sellTicket(){
        if(num > 0){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "正在出票,票号为:" + num--);
        }
    }
}

